/**
 * 链接删除管理接口
 */
import {
  directus,
  getItems,
  getItemById,
  createItem,
  updateItems,
  deleteItem,
} from "@/api/directus";

/** 视图/集合 */
export const COLLECTION_LINK_DELETION_VIEW = "links_filter" as const;

/** 状态 */
export type LinkDeletionStatus = "published" | "draft" | "archived";

/** 记录结构 */
export interface LinkDeletionItem {
  id: number | string;
  link_name?: string;
  url?: string;
  memo?: string;
  status?: LinkDeletionStatus;
  date_created?: string;
}

/** 列表查询参数 */
export interface LinkDeletionListParams {
  page?: number;
  pageSize?: number;
  keyword?: string;
  sort?: string | string[];
  excludeStatus?: LinkDeletionStatus | null;
  signal?: AbortSignal;
}

/** 列表返回 */
export interface LinkDeletionListResult {
  list: LinkDeletionItem[];
  total: number;
}

/* ----------------------- 工具函数 ----------------------- */

const FIELDS_BASE = ["id", "link_name", "url", "memo", "status", "date_created"] as const;
type FieldKey = (typeof FIELDS_BASE)[number];

const normalizeSort = (sort?: string | string[]) =>
  Array.isArray(sort) ? sort.filter(Boolean) : sort ? [sort] : [];

const safeTrim = (s?: string) => (typeof s === "string" ? s.trim() : "");

const buildFilter = ({
  excludeStatus,
  keyword,
  ids,
}: {
  excludeStatus?: LinkDeletionStatus | null;
  keyword?: string;
  ids?: Array<number | string>;
}) => {
  const filter: Record<string, any> = {};
  if (excludeStatus) filter.status = { _neq: excludeStatus };
  const k = safeTrim(keyword);
  if (k) {
    filter._or = [
      { link_name: { _icontains: k } },
      { url: { _icontains: k } },
      { memo: { _icontains: k } },
    ];
  }
  if (ids && ids.length) filter.id = { _in: ids };
  return filter;
};

function escapeCsvCell(v: any) {
  const s = String(v ?? "");
  return `"${s.replace(/"/g, '""')}"`;
}

/* ----------------------- 获取分页列表 ----------------------- */

export async function getLinkDeletionList(
  params: LinkDeletionListParams = {}
): Promise<LinkDeletionListResult> {
  const {
    page = 1,
    pageSize = 25,
    keyword = "",
    sort = "id",
    excludeStatus = "archived",
    signal,
  } = params;

  const res: any = await getItems<LinkDeletionItem>(COLLECTION_LINK_DELETION_VIEW, {
    page,
    limit: pageSize,
    fields: FIELDS_BASE as unknown as FieldKey[],
    sort: normalizeSort(sort),
    filter: buildFilter({ excludeStatus, keyword }),
    meta: "filter_count",
    signal,
  });

  const list: LinkDeletionItem[] = res?.data ?? res ?? [];
  const total: number = res?.meta?.filter_count ?? res?.meta?.total_count ?? list.length;
  return { list, total };
}

/* ----------------------- 新增 / 编辑 / 详情 ----------------------- */

/** 新增 */
export function createLinkDeletion(payload: {
  link_name: string;
  url: string;
  memo?: string;
  status?: LinkDeletionStatus;
}) {
  return createItem<LinkDeletionItem>(COLLECTION_LINK_DELETION_VIEW, payload);
}

/** 编辑 */
export async function updateLinkDeletion(
  id: number | string,
  payload: Partial<LinkDeletionItem>
) {
  const data = await updateItems<LinkDeletionItem>(COLLECTION_LINK_DELETION_VIEW, [
    { id, ...payload },
  ]);
  return Array.isArray(data) ? data[0] : data;
}

/** 详情 */
export function getLinkDeletionById(id: number | string) {
  return getItemById<LinkDeletionItem>(COLLECTION_LINK_DELETION_VIEW, id, [
    "id",
    "link_name",
    "url",
    "memo",
    "status",
    "date_created",
  ]);
}

/* ----------------------- 删除 / 批量删除 ----------------------- */

/** 单删 */
export function deleteLinkDeletion(id: number | string) {
  return deleteItem(COLLECTION_LINK_DELETION_VIEW, id);
}

/** 批量删除 */
export async function deleteLinkDeletions(ids: Array<number | string>) {
  if (!ids?.length) return;
  try {
    await directus.delete(`/items/${COLLECTION_LINK_DELETION_VIEW}`, {
      headers: { "Content-Type": "application/json" },
      data: { keys: ids },
    });
  } catch {
    await Promise.all(ids.map((id) => deleteLinkDeletion(id)));
  }
}

/* ----------------------- 启用 / 停用 ----------------------- */

export async function enableLinkDeletion(id: number | string) {
  const data = await updateItems<LinkDeletionItem>(COLLECTION_LINK_DELETION_VIEW, [
    { id, status: "published" },
  ]);
  return Array.isArray(data) ? data[0] : data;
}

export async function disableLinkDeletion(id: number | string) {
  const data = await updateItems<LinkDeletionItem>(COLLECTION_LINK_DELETION_VIEW, [
    { id, status: "draft" },
  ]);
  return Array.isArray(data) ? data[0] : data;
}

/* ----------------------- 导出 ----------------------- */

export interface LinkDeletionExportParams {
  ids?: Array<number | string>;
  keyword?: string;
  sort?: string | string[];
  excludeStatus?: LinkDeletionStatus | null;
  batchSize?: number;
  signal?: AbortSignal;
}

async function fetchByIds(
  ids: Array<number | string>,
  fields: string[] = ["id", "link_name", "url", "memo", "status", "date_created"],
  sort: string | string[] = "id",
  batchSize = 500,
  signal?: AbortSignal
) {
  const all: LinkDeletionItem[] = [];
  for (let i = 0; i < ids.length; i += batchSize) {
    const slice = ids.slice(i, i + batchSize);
    const res: any = await getItems<LinkDeletionItem>(COLLECTION_LINK_DELETION_VIEW, {
      page: 1,
      limit: slice.length,
      fields,
      sort: normalizeSort(sort),
      filter: { id: { _in: slice } },
      meta: "filter_count",
      signal,
    });
    all.push(...(res?.data ?? res ?? []));
  }
  return all;
}

async function fetchAllByKeyword(
  keyword = "",
  excludeStatus: LinkDeletionStatus | null = "archived",
  sort: string | string[] = "id",
  batchSize = 500,
  signal?: AbortSignal
) {
  const fields = ["id", "link_name", "url", "memo", "status", "date_created"];
  const filter = buildFilter({ excludeStatus, keyword });

  let page = 1;
  const all: LinkDeletionItem[] = [];
  let total = 0;

  while (true) {
    const res: any = await getItems<LinkDeletionItem>(COLLECTION_LINK_DELETION_VIEW, {
      page,
      limit: batchSize,
      fields,
      sort: normalizeSort(sort),
      filter,
      meta: "filter_count",
      signal,
    });
    const list: LinkDeletionItem[] = res?.data ?? res ?? [];
    total = res?.meta?.filter_count ?? res?.meta?.total_count ?? total;
    all.push(...list);
    if (!list.length || all.length >= total) break;
    page += 1;
  }

  return all;
}

export async function exportLinkDeletionsCSV(
  params: LinkDeletionExportParams = {}
): Promise<Blob> {
  const {
    ids,
    keyword = "",
    sort = "id",
    excludeStatus = "archived",
    batchSize = 500,
    signal,
  } = params;

  const data =
    Array.isArray(ids) && ids.length
      ? await fetchByIds(
        ids,
        ["id", "link_name", "url", "memo", "status", "date_created"],
        sort,
        batchSize,
        signal
      )
      : await fetchAllByKeyword(keyword, excludeStatus, sort, batchSize, signal);

  const header = ["名称", "链接地址", "备注", "状态", "创建时间"];
  const rows = data.map((it) => [
    it.link_name || "",
    it.url || "",
    it.memo || "",
    it.status === "published" ? "启用" : "停用",
    it.date_created || "",
  ]);

  const csv = [header, ...rows]
    .map((r) => r.map(escapeCsvCell).join(","))
    .join("\r\n");

  return new Blob(["\uFEFF" + csv], { type: "text/csv;charset=utf-8" });
}

export async function exportLinkDeletionsJSON(
  params: LinkDeletionExportParams = {}
): Promise<Blob> {
  const {
    ids,
    keyword = "",
    sort = "id",
    excludeStatus = "archived",
    batchSize = 500,
    signal,
  } = params;

  const data =
    Array.isArray(ids) && ids.length
      ? await fetchByIds(
        ids,
        ["id", "link_name", "url", "memo", "status", "date_created"],
        sort,
        batchSize,
        signal
      )
      : await fetchAllByKeyword(keyword, excludeStatus, sort, batchSize, signal);

  const json = JSON.stringify(data, null, 2);
  return new Blob([json], { type: "application/json;charset=utf-8" });
}

/* ----------------------- 导入 ----------------------- */

export interface LinkDeletionImportResult {
  total?: number;
  inserted?: number;
  created?: number;
  updated?: number;
  skipped?: number;
  failed?: number;
  details?: any;
}

export interface LinkDeletionImportExtra {
  format?: "csv" | "json";
  overwrite?: boolean;
  signal?: AbortSignal;
  filename?: string;
}

/** 通过文件导入 */
export async function importLinkDeletionsFile(
  file: File | Blob,
  extra?: LinkDeletionImportExtra
): Promise<LinkDeletionImportResult> {
  const fd = new FormData();
  const name =
    extra?.filename || (file instanceof File ? file.name : "links_filter.csv");
  fd.append("file", file, name);
  if (extra?.format) fd.append("format", extra.format);
  if (typeof extra?.overwrite === "boolean") {
    fd.append("overwrite", String(extra.overwrite));
  }

  const res: any = await directus.post(`/utils/import/links_filter`, fd, {
    signal: extra?.signal as any,
  });
  return (res?.data?.data ?? res?.data ?? {}) as LinkDeletionImportResult;
}
